﻿using System;
using System.Linq;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Utils;

namespace Pap.Services.Responsible
{
    /// <summary>
    /// 
    /// </summary>
    class ResponsibleService : IResponsibleService
    {
        /// <summary>
        /// 
        /// </summary>
        IDatabase _dataBase;
        /// <summary>
        /// 
        /// </summary>
        IWorkFlow _WorkFlow;
        /// <summary>
        /// 
        /// </summary>
        IWorkflowService _WorkFlowService;

        /// <summary>
        /// Initializes a new instance of the <see cref="ResponsibleService"/> class.
        /// </summary>
        /// <param name="Database">The database.</param>
        /// <param name="WorkFlow">The work flow.</param>
        /// <param name="WorkFlowService">The work flow service.</param>
        public ResponsibleService(IDatabase Database, IWorkFlow WorkFlow, IWorkflowService WorkFlowService)
        {
            _dataBase = Database;
            _WorkFlow = WorkFlow;
            _WorkFlowService = WorkFlowService;
        }

        /// <summary>
        /// Gets the free responsible ID.
        /// </summary>
        /// <param name="committeeID">The committee ID.</param>
        /// <param name="projectID">The project ID.</param>
        /// <returns></returns>
        public Guid GetFreeResponsibleID(Guid committeeID, IProject project)
        {
            var wfProcesses = _WorkFlowService.GetInStep(Pap.Services.WorkflowEngine.Steps.LoanCreated).Union(
                _WorkFlowService.GetInStep(Pap.Services.WorkflowEngine.Steps.ResearchAndStudy));

            var strPermission = Permissions.ResponsibleWaitingList.ToString().ToLower();

            var result = from user in _dataBase.Users
                         join userRole in _dataBase.UsersRole on user.UserID equals userRole.UserID
                         join role in _dataBase.Roles on userRole.RoleID equals role.RoleID
                         join rolePemrmision in _dataBase.RolesPermission on role.RoleID equals rolePemrmision.RoleID
                         join permission in _dataBase.Permissions on rolePemrmision.PermissionID equals
                             permission.PermissionID
                         orderby user.CustomerLoans.Where(cl => wfProcesses.Contains(cl.LoanID)).Count() ascending
                         where user.UsersCommittees.Select(uc => uc.CommitteeID).Contains(committeeID)
                               && permission.PermissionName.ToLower() == strPermission
                         select user;

            foreach (IUser user in result)
            {
                foreach (IProject proj in user.Projects)
                {
                    if (proj.ProjectID == project.ProjectID)
                        return user.UserID;
                }
            }
            return new Guid();

            //return result.First(user => user.Projects.Select(proj => proj.ProjectID).Contains(project.ProjectID)).UserID;
        }

        /// <summary>
        /// Gets the free responsible ID temp.
        /// </summary>
        /// <param name="committeeID">The committee ID.</param>
        /// <returns></returns>
        public Guid GetFreeResponsibleIDTemp(Guid committeeID)
        {
            var query = (from loan in _dataBase.CustomerLoans
                         join user in _dataBase.Users on loan.ResponsibleID equals user.UserID into tl
                         from user in tl.DefaultIfEmpty()
                         where loan.CommitteeID == committeeID
                         select new { loanID = loan.LoanID, UserID = user.UserID });

            return (from item in query
                    group item by item.UserID into y
                    select new { UserID = y.Key, Count = y.Count() }).Min().UserID;

        }
    }
}
